home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / rclesrc.10 / ircle sources / MsgWindows.p < prev   
Encoding:
Text File  |  1992-09-05  |  10.4 KB  |  426 lines

  1. {    ircle - Internet Relay Chat client    }
  2. {    File: MsgWindows     }
  3. {    Copyright ⌐ 1992 Olaf Titz (s_titz@iravcl.ira.uka.de)    }
  4.  
  5. {    This program is free software; you can redistribute it and/or modify    }
  6. {    it under the terms of the GNU General Public License as published by    }
  7. {    the Free Software Foundation; either version 2 of the License, or    }
  8. {    (at your option) any later version.    }
  9.  
  10. {    This program is distributed in the hope that it will be useful,    }
  11. {    but WITHOUT ANY WARRANTY; without even the implied warranty of    }
  12. {    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    }
  13. {    GNU General Public License for more details.    }
  14.  
  15. {    You should have received a copy of the GNU General Public License    }
  16. {    along with this program; if not, write to the Free Software    }
  17. {    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    }
  18.  
  19. unit MsgWindows;
  20. {╩Deals with windows for displaying messages }
  21.  
  22. interface
  23. uses
  24.     ApplBase;
  25.  
  26. const
  27.     MW_MAGIC = 'MWIN';
  28.  
  29. type
  30.     MWHndl = ^MWPtr;    { This gets stored in the window's refCon }
  31.     MWPtr = ^MWRec;
  32.     MWRec = record
  33.             magic: OSType;            { for checking }
  34.             w: WindowPtr;            { the Window }
  35.             whenDone: ProcPtr;        { called on closing }
  36.             hscr, vscr: ControlHandle;    { scroll bars }
  37.             t: TEHandle;                { TextEdit record }
  38.             vislines: integer            { # of visible lines }
  39.         end;
  40.  
  41. var
  42.     MWActive: MWHndl;    { MWHndl of active window; or else nil }
  43.     MWdefaultFont, MWdefaultSize: integer;
  44.  
  45. procedure InitMsgWindows;
  46. { startup }
  47.  
  48. function NewMWindow (var title: string; DoWhenDone: ProcPtr): MWHndl;
  49. { Make a new window. DoWhen done gets called when user wants to }
  50. { close window; to be declared as: procedure DoWhenDone(w:WindowPtr) }
  51.  
  52. procedure SetFontSize (window: MWHndl; font, size: integer);
  53. { Change window font/size }
  54.  
  55. procedure DeleteMWindow (window: MWHndl);
  56. {╩Delete window }
  57.  
  58. procedure MWMessage (window: MWHndl; var msg: string);
  59. { Display message at bottom of window }
  60.  
  61. implementation
  62.  
  63. const
  64.     MW_MAXLEN = 10000;     { maximum # of chars to store }
  65.     MW_KILLEN = 3000;        { # of chars to kill if window exceeds MW_MAXLEN }
  66.  
  67. var
  68.     glob: MWHndl;
  69.     cornerstone: rect;
  70.     flood: integer;
  71.  
  72. function EvtMW (var e: EventRecord): MWHndl;
  73.     var
  74.         w: MWHndl;
  75.     begin
  76.         w := MWHndl(GetWRefCon(WindowPtr(e.message)));
  77.         if w <> nil then
  78.             if w^^.magic <> MW_MAGIC then
  79.                 w := nil;
  80.         EvtMW := w
  81.     end;
  82.  
  83. procedure SetWDimen (win: MWHndl; left, top, width, height: integer);
  84.     var
  85.         r: Rect;
  86.     begin
  87.         if left + width < 10 then
  88.             left := 10 - width;
  89.         win^^.vislines := (height - 20) div win^^.t^^.lineheight;
  90.         height := win^^.vislines * win^^.t^^.lineheight + 20;
  91.         SetRect(r, 3, 2, width - 17, height - 17);
  92.         win^^.t^^.destRect := r;
  93.         r.top := r.top + 1;
  94.         win^^.t^^.viewRect := r;
  95.         MoveWindow(win^^.w, left, top, true);
  96.         SizeWindow(win^^.w, width, height, false);
  97.         EraseRect(win^^.w^.portRect);
  98.         MoveControl(win^^.hscr, -1, height - 15);
  99.         SizeControl(win^^.hscr, width - 13, 16);
  100.         MoveControl(win^^.vscr, width - 15, -1);
  101.         SizeControl(win^^.vscr, 16, height - 13);
  102.         TECalText(win^^.t);
  103.         TEPinScroll(0, 32767, win^^.t);
  104.         if win^^.t^^.nlines <= win^^.vislines then
  105.             SetCtlMax(win^^.vscr, 0)
  106.         else
  107.             SetCtlMax(win^^.vscr, win^^.t^^.nlines - win^^.vislines);
  108.         SetCtlValue(win^^.vscr, 0);
  109.         InvalRect(win^^.w^.portRect);
  110.         ShowWindow(win^^.w);
  111.         SelectWindow(win^^.w);
  112.     end;
  113.  
  114. procedure ResetWDimen (w: MWHndl);
  115.     begin
  116.         with w^^.w^.portBits.bounds do
  117.             SetWDimen(w, -left, -top, w^^.w^.portRect.right, w^^.w^.portRect.bottom)
  118.     end;
  119.  
  120. procedure vscroll (o, n: integer);
  121.     begin
  122.         SetCtlValue(glob^^.vscr, o - n);
  123.         TEPinScroll(0, n * glob^^.t^^.lineheight, glob^^.t);
  124.     end;
  125. procedure Vscrolling (cc: ControlHandle; part: integer);
  126.     begin
  127.         case part of
  128.             inPageUp: 
  129.                 vscroll(GetCtlValue(glob^^.vscr), glob^^.vislines - 1);
  130.             inPageDown: 
  131.                 vscroll(GetCtlValue(glob^^.vscr), 1 - glob^^.vislines);
  132.             inUpButton: 
  133.                 vscroll(GetCtlValue(glob^^.vscr), 1);
  134.             inDownButton: 
  135.                 vscroll(GetCtlValue(glob^^.vscr), -1);
  136.             otherwise
  137.         end;
  138.     end;
  139.  
  140. function inContentHandler (var e: EventRecord): boolean;
  141.     var
  142.         p: MWHndl;
  143.         c: ControlHandle;
  144.         pa, i: integer;
  145.     begin
  146.         p := EvtMW(e);
  147.         if p <> nil then begin
  148.             glob := p;
  149.             GlobalToLocal(e.where);
  150.             pa := FindControl(e.where, p^^.w, c);
  151.             case pa of
  152.                 inUpButton, inDownButton, inPageUp, inPageDown: 
  153.                     if c = p^^.vscr then
  154.                         pa := TrackControl(c, e.where, @Vscrolling);
  155.                 inThumb: 
  156.                     if c = p^^.vscr then begin
  157.                         i := GetCtlValue(c);
  158.                         pa := TrackControl(c, e.where, nil);
  159.                         if pa = inThumb then
  160.                             vscroll(i, i - GetCtlValue(c));
  161.                     end;
  162.                 otherwise
  163.                     if PtInRect(e.where, p^^.t^^.viewRect) then
  164.                         TEClick(e.where, false, p^^.t);
  165.             end;
  166.             inContentHandler := true;
  167.         end
  168.         else
  169.             inContentHandler := false;
  170.     end;
  171.  
  172. function inGrowHandler (var e: EventRecord): boolean;
  173.     var
  174.         p: MWHndl;
  175.         r: Rect;
  176.         ii: longint;
  177.     begin
  178.         p := EvtMW(e);
  179.         if p <> nil then begin
  180.             SetRect(r, 32, 32, 32767, 32767);
  181.             ii := GrowWindow(p^^.w, e.where, r);
  182.             inGrowHandler := true;
  183.             if ii <> 0 then
  184.                 with p^^.w^.portBits.bounds do
  185.                     SetWDimen(p, -left, -top, LoWord(ii), HiWord(ii));
  186.         end
  187.         else
  188.             inGrowHandler := false;
  189.     end;
  190.  
  191. procedure XCALL (w: WindowPtr; p: ProcPtr);
  192. inline
  193.     $205F, $4E90;        { movea.l (a7)+,a0; jsr (a0) }
  194.  
  195. function inGoAwayHandler (var e: EventRecord): boolean;
  196.     var
  197.         p: MWHndl;
  198.     begin
  199.         p := EvtMW(e);
  200.         if p <> nil then begin
  201.             if TrackGoAway(p^^.w, e.where) then
  202.                 if p^^.whenDone <> nil then
  203.                     XCALL(p^^.w, p^^.whenDone);
  204.             inGoAwayHandler := true;
  205.         end
  206.         else
  207.             inGoAwayHandler := false;
  208.     end;
  209.  
  210. function inZoomInOutHandler (var e: EventRecord): boolean;
  211.     var
  212.         p: MWHndl;
  213.     begin
  214.         p := EvtMW(e);
  215.         if p <> nil then begin
  216.             if TrackBox(p^^.w, e.where, e.what - mouseMsg) then begin
  217.                 HideWindow(p^^.w);
  218.                 ZoomWindow(p^^.w, e.what - mouseMsg, false);
  219.                 ResetWDimen(p);
  220.                 inZoomInOutHandler := true;
  221.             end
  222.         end
  223.         else
  224.             inZoomInOutHandler := false;
  225.     end;
  226.  
  227. function updateHandler (var e: EventRecord): boolean;
  228.     var
  229.         p: MWHndl;
  230.     begin
  231.         flood := 0;
  232.         p := EvtMW(e);
  233.         if p <> nil then begin
  234.             BeginUpdate(p^^.w);
  235.             DrawControls(p^^.w);
  236.             TEUpdate(p^^.w^.portRect, p^^.t);
  237.             DrawGrowIcon(p^^.w);
  238.             EndUpdate(p^^.w);
  239.             updateHandler := true;
  240.         end
  241.         else
  242.             updateHandler := false;
  243.     end;
  244.  
  245. function activateHandler (var e: EventRecord): boolean;
  246.     var
  247.         p: MWHndl;
  248.         r: Rect;
  249.         i: integer;
  250.     begin
  251.         activateHandler := false;
  252.         p := EvtMW(e);
  253.         if p <> nil then begin
  254.             if odd(e.modifiers) then begin
  255.                 HiliteControl(p^^.vscr, 0);
  256.                 TEActivate(p^^.t);
  257.                 mwActive := p;
  258.             end
  259.             else begin
  260.                 HiliteControl(p^^.vscr, 255);
  261.                 TEDeactivate(p^^.t);
  262.                 mwActive := nil;
  263.             end;
  264.             with p^^.w^.portRect do
  265.                 SetRect(r, right - 14, bottom - 14, right, bottom);
  266.             EraseRect(r);
  267. {    InvalRect(p^^.w^.portRect);}
  268.             InvalRect(r);
  269.         end
  270.         else
  271.             mwActive := nil;
  272.     end;
  273.  
  274. function editHandler (var e: EventRecord): boolean;
  275.     var
  276.         i: integer;
  277.     begin
  278.         if mwActive <> nil then
  279.             if e.message = 4 then begin
  280.                 TECopy(mwActive^^.t);
  281.                 if ZeroScrap = 0 then
  282.                     i := TEToScrap;
  283.                 editHandler := true
  284.             end
  285.             else if e.message = 7 then begin
  286.                 TESetSelect(0, 32767, mwActive^^.t);
  287.                 SetCtlValue(mwActive^^.vscr, 0);
  288.                 editHandler := true
  289.             end
  290.             else
  291.                 editHandler := false
  292.         else
  293.             editHandler := false
  294.     end;
  295.  
  296. procedure ForceUpdate (w: MWHndl);
  297.     var
  298.         ee: EventRecord;
  299.         b: boolean;
  300.         p0: GrafPtr;
  301.     begin
  302.         GetPort(p0);
  303.         SetPort(w^^.w);
  304.         InvalRect(w^^.w^.portRect);
  305.         ee.message := longint(w^^.w);
  306.         b := updateHandler(ee);
  307.         SetPort(p0)
  308.     end;
  309.  
  310.  
  311. procedure InitMsgWindows;
  312.     var
  313.         i: integer;
  314.     begin
  315.         SetRect(cornerstone, 2, 40, 500, 40);
  316.         i := ApplTask(@inContentHandler, mouseMsg + inContent);
  317.         i := ApplTask(@inGrowHandler, mouseMsg + inGrow);
  318.         i := ApplTask(@inGoAwayHandler, mouseMsg + inGoAway);
  319.         i := ApplTask(@inZoomInOutHandler, mouseMsg + inZoomIn);
  320.         i := ApplTask(@inZoomInOutHandler, mouseMsg + inZoomOut);
  321.         i := ApplTask(@updateHandler, updateEvt);
  322.         i := ApplTask(@activateHandler, activateEvt);
  323.         i := ApplTask(@editHandler, menuMsg + editMenu);
  324.         mwActive := nil;
  325.         flood := 0;
  326.         MWdefaultFont := monaco;
  327.         MWdefaultSize := 9;
  328.     end;
  329.  
  330. procedure SetFontSize (window: MWHndl; font, size: integer);
  331.     var
  332.         f: FontInfo;
  333.     begin
  334.         TextFont(font);
  335.         TextSize(size);
  336.         GetFontInfo(f);
  337.         with window^^.t^^ do begin
  338.             txFont := font;
  339.             txSize := size;
  340.             lineheight := f.descent + f.leading + f.ascent;
  341.             fontascent := f.ascent;
  342.         end;
  343.         with window^^.w^.portBits.bounds do
  344.             window^^.vislines := (3 * (bottom - top - 45) div 4) div window^^.t^^.lineheight;
  345.         with window^^.w^.portBits.bounds do
  346.             SetWDimen(window, -left, -top, 80 * CharWidth('x') + 22, window^^.vislines * window^^.t^^.lineheight + 16);
  347.     end;
  348.  
  349. function NewMWindow (var Title: string; DoWhenDone: ProcPtr): MWHndl;
  350.     var
  351.         h: MWHndl;
  352.         p0: GrafPtr;
  353.         r: Rect;
  354.         f: FontInfo;
  355.     begin
  356.         r := cornerstone;
  357.         OffsetRect(cornerstone, 8, 16);
  358.         h := MWHndl(NewHandle(sizeof(MWRec)));
  359.         if h <> nil then begin
  360.             h^^.w := NewWindow(nil, r, title, false, 8, WindowPtr(-1), true, longint(h));
  361.             if h^^.w <> nil then begin
  362.                 GetPort(p0);
  363.                 SetPort(h^^.w);
  364.                 h^^.magic := MW_MAGIC;
  365.                 h^^.hscr := NewControl(h^^.w, r, '', true, 0, 0, 0, 16, 0);
  366.                 h^^.vscr := NewControl(h^^.w, r, '', true, 0, 0, 0, 16, 0);
  367.                 h^^.whenDone := DoWhenDone;
  368.                 h^^.t := TENew(r, r);
  369.                 TEAutoView(true, h^^.t);
  370.                 TEActivate(h^^.t);
  371.                 SetFontSize(h, MWdefaultFont, MWdefaultSize);
  372.                 SetPort(p0)
  373.             end
  374.         end;
  375.         NewMWindow := h
  376.     end;
  377.  
  378.  
  379. procedure DeleteMWindow (window: MWHndl);
  380.     begin
  381.         HideWindow(window^^.w);
  382.         TEDispose(window^^.t);
  383.         DisposeControl(window^^.hscr);
  384.         DisposeControl(window^^.vscr);
  385.         DisposeWindow(window^^.w);
  386.         DisposHandle(Handle(window));
  387.     end;
  388.  
  389. procedure MWMessage (window: MWHndl; var msg: string);
  390.     var
  391.         p0: GrafPtr;
  392.         i: integer;
  393.     begin
  394.         if window <> nil then begin
  395.             GetPort(p0);
  396.             SetPort(window^^.w);
  397.             TEDeactivate(window^^.t);
  398.             if window^^.t^^.teLength > MW_MAXLEN then begin
  399.                 i := Munger(Handle(window^^.t^^.hText), 0, nil, MW_KILLEN, ptr(1), 0);
  400.                 TECalText(window^^.t);
  401.                 TESelView(window^^.t);
  402.                 ForceUpdate(window);
  403.             end;
  404.             if pos(chr(7), msg) > 0 then
  405.                 SysBeep(10);
  406.             for i := 1 to length(msg) do
  407.                 if msg[i] < ' ' then
  408.                     msg[i] := ' ';
  409.             msg[length(msg) + 1] := chr(13);
  410.             TESetSelect(32767, 32767, window^^.t);
  411.             TEInsert(@msg[1], length(msg) + 1, window^^.t);
  412.             TESelView(window^^.t);
  413.             if window^^.w = FrontWindow then
  414.                 TEActivate(window^^.t);
  415.             i := window^^.t^^.nlines - window^^.vislines + 1;
  416.             if i < 0 then
  417.                 i := 0;
  418.             SetCtlMax(window^^.vscr, i);
  419.             SetCtlValue(window^^.vscr, i);
  420. {    InvalRect(window^^.t^^.viewRect);}
  421.             SetPort(p0);
  422.         end;
  423.     end;
  424.  
  425.  
  426. end.